//////////////////////////////////////////////////////////////////////
//
// NO_Function.h header for the $1 class.
//
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
#ifndef NO_Function_H
#define NO_Function_H

//////////////////////////////////////////////////////////////////////////
#include "NO_Includes.h"

//////////////////////////////////////////////////////////////////////////
class NO_Type;
class NO_TypeList;
class NO_IFunction;

//////////////////////////////////////////////////////////////////////////
// NO_IFuncObject
//////////////////////////////////////////////////////////////////////////
class NO_DLL_TAL NO_IFuncObject
{
public:	
	//////////////////////////////////////////////////////////////////////////
	// con/destruction
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	NO_IFuncObject(NO_IFunction const * func);
	virtual ~NO_IFuncObject();
	
	//////////////////////////////////////////////////////////////////////////
	// retrieve
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	virtual NO_ObjectList&		getParameter(NO_ObjectList&)const = 0;
	virtual NO_Object const &	getResult(void)				const = 0;
	virtual NO_Object const &	getObject(void)				const = 0;
	std::string const &			getName(void)				const;
	NO_UInt32					getID(void)					const;

	//////////////////////////////////////////////////////////////////////////
	// use
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	virtual void operator() (void) const = 0;

private:
	//////////////////////////////////////////////////////////////////////////
	NO_IFunction const * func;
};

//////////////////////////////////////////////////////////////////////////
// NO_IFuncBind
//////////////////////////////////////////////////////////////////////////
class NO_DLL_TAL NO_IFuncBind
{
public:	
	//////////////////////////////////////////////////////////////////////////
	// con/destruction
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	NO_IFuncBind(NO_IFunction const * func);
	virtual ~NO_IFuncBind();
	
	//////////////////////////////////////////////////////////////////////////
	// retrieve
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	virtual NO_TypeList&		getParameter(NO_TypeList&)  const = 0;
	virtual NO_Type const &		getResult(void)				const = 0;
	virtual NO_Object const &	getObject(void)				const = 0;
	std::string const &			getName(void)				const;
	NO_UInt32					getID(void)					const;
	
	//////////////////////////////////////////////////////////////////////////
	// use
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	virtual void operator() (NO_ObjectList& params, NO_Object& result)	const = 0;
	virtual void operator() (NO_ObjectList& params)						const = 0;
	
private:
	//////////////////////////////////////////////////////////////////////////
	NO_IFunction const * func;
};

//////////////////////////////////////////////////////////////////////////
// NO_IFunction
//////////////////////////////////////////////////////////////////////////
class NO_DLL_TAL NO_IFunction
{
public:	
	//////////////////////////////////////////////////////////////////////////
	// con/destruction
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	NO_IFunction(const std::string& name);
	NO_IFunction(const NO_Int8* name);
	virtual ~NO_IFunction();
	
	//////////////////////////////////////////////////////////////////////////
	// use
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	virtual void operator() (NO_Object& obj, NO_ObjectList& params, NO_Object& ret)	const = 0; 
	virtual void operator() (NO_Object& obj, NO_ObjectList& params)					const = 0; 
	virtual void operator() (NO_ObjectList& params, NO_Object& ret)					const = 0 ;
	virtual void operator() (NO_ObjectList& params)									const = 0 ;
	
	//////////////////////////////////////////////////////////////////////////
	virtual NO_IFuncBind* bind (NO_Object& o)	const = 0;
	virtual NO_IFuncBind* bind (void)			const = 0;
	
	//////////////////////////////////////////////////////////////////////////
	virtual NO_IFuncObject* object (NO_Object& o, NO_ObjectList& p, NO_Object& r)	const = 0;
	virtual NO_IFuncObject* object (NO_Object& o, NO_ObjectList& p)					const = 0;
	virtual NO_IFuncObject* object (NO_ObjectList& p, NO_Object& r)					const = 0;
	virtual NO_IFuncObject* object (NO_ObjectList& p)								const = 0;
	
	//////////////////////////////////////////////////////////////////////////
	// retrieve
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	virtual NO_Type const &		getObjectType	(void) const = 0;
	virtual NO_Type const &		getReturnType	(void) const = 0;
	virtual NO_TypeList&		getParameter	(NO_TypeList&) const = 0;
	virtual NO_Boolean			getIsStatic		(void) const = 0;
	virtual NO_Boolean			getIsMember		(void) const = 0;
	std::string const &			getName			(void) const;
	NO_UInt32					getID			(void) const;

protected:
	//////////////////////////////////////////////////////////////////////////
	friend class NO_FunctionFriend;
	
	//////////////////////////////////////////////////////////////////////////
	typedef fastdelegate::detail::DefaultVoid DV;
	
	//////////////////////////////////////////////////////////////////////////
	NO_UInt32 id;
	std::string name;
	NO_IFunction* next;
};

//////////////////////////////////////////////////////////////////////////
// class NO_MemberFriend definition
//////////////////////////////////////////////////////////////////////////
class NO_DLL_TAL NO_FunctionFriend  
{
protected:
	//////////////////////////////////////////////////////////////////////////
	NO_IFunction*	getNext	(const NO_IFunction*)			const;
	void			setNext	(NO_IFunction*, NO_IFunction*)	const;
	void			setID	(NO_IFunction*, NO_UInt32)		const;
};

//////////////////////////////////////////////////////////////////////////
// class NO_FunctionList definition
//////////////////////////////////////////////////////////////////////////
class NO_DLL_TAL NO_FunctionList : public NO_FunctionFriend 
{
public:
	//////////////////////////////////////////////////////////////////////
	// con/destruction
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	NO_FunctionList(void);
	~NO_FunctionList(void);
	
	//////////////////////////////////////////////////////////////////////////
	// modify
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	NO_Boolean addFunction(NO_IFunction*);
	
	//////////////////////////////////////////////////////////////////////////
	// retrieve
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	const NO_IFunction* findFunctionImpl(const NO_Int8*, const NO_TypeList&)const;
	const NO_IFunction* findFunctionImpl(NO_UInt32 ID)						const;
	
	//////////////////////////////////////////////////////////////////////////
	const NO_IFunction* beginFunctionImpl	(void) const;
	const NO_IFunction* endFunctionImpl		(void) const;
	const NO_IFunction* nextFunctionImpl	(const NO_IFunction*) const;
	
private:
	//////////////////////////////////////////////////////////////////////
	NO_IFunction* first;
	NO_IFunction* last;
};

//////////////////////////////////////////////////////////////////////////
// class NO_IFunctionList definition
//////////////////////////////////////////////////////////////////////////
class NO_DLL_TAL NO_NoneFunctions 
{
public:
	//////////////////////////////////////////////////////////////////////
	// con/destruction
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	NO_NoneFunctions(void);
	~NO_NoneFunctions(void);
	
	//////////////////////////////////////////////////////////////////////////
	// retrieve
	//////////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	const NO_IFunction* findFunctionImpl(const NO_Int8*, const NO_TypeList&)	const;
	const NO_IFunction* findFunctionImpl(NO_UInt32 ID)							const;
	
	//////////////////////////////////////////////////////////////////////////
	const NO_IFunction* beginFunctionImpl	(void) const;
	const NO_IFunction* endFunctionImpl		(void) const;
	const NO_IFunction* nextFunctionImpl	(const NO_IFunction*) const;
};

#endif 
